#include <iomanip>
#include "gsmSnifferManager.h"

using namespace std;
gsmSnfManager::gsmSnfManager()
{
}
gsmSnfManager* gsmSnfManager::instance()
{
    static gsmSnfManager instance_;
    return &instance_;
}

void gsmSnfManager::initGsmSnfManager()
{
    MobileCellInfo_.clear();
    UnicomCellInfo_.clear();
}

void gsmSnfManager::handleNbCellInfo(bool isMobile, neighboringCellInfo cell)
{
    std::vector<neighboringCell> *tmpInfo;
    if (isMobile)
    {
        tmpInfo = &MobileCellInfo_;     
    }
    else
    {
        tmpInfo = &UnicomCellInfo_;
    }
    neighboringCell tmpcell;
    tmpcell.bGlobalCellId = cell.bGlobalCellId;
    memcpy(tmpcell.bPLMNId, cell.bPLMNId, 5);
    tmpcell.cRSSI = cell.cRSSI;
    tmpcell.wLAC = cell.wLAC;
    tmpcell.wBSIC = cell.wBSIC;
    tmpcell.wARFCN = cell.wARFCN;
    tmpcell.cC1 = cell.cC1;
    tmpcell.bNbCellNum = cell.bNbCellNum;
    tmpcell.bReserved = cell.bReserved;
    tmpcell.bC2 = cell.bC2;
    memcpy(tmpcell.stNbCell, cell.stNbCell, sizeof(cellItem) * 32);
    if (tmpInfo->size() == 5)
    {
        
        if ((*tmpInfo)[4].cRSSI < cell.cRSSI)
        {
            tmpInfo->pop_back();
            tmpInfo->push_back(tmpcell);
        }
    }
    else
    {
        tmpInfo->push_back(tmpcell);
    }
    sort(tmpInfo->begin(), tmpInfo->end(), greater<neighboringCell>());

}

void gsmSnfManager::handleSnifferResult()
{
    MobileCellItem_.clear();
    UnicomCellItem_.clear();
    for (uint32_t i = 0; i < MobileCellInfo_.size(); i++)
    {
        for (int32_t j = 0; j < MobileCellInfo_[i].bNbCellNum; j++)
        {
            bool isInList = false;
            for (vector<cellItemInfo>::iterator it = MobileCellItem_.begin(); it != MobileCellItem_.end(); it++)
            {
                if (MobileCellInfo_[i].stNbCell[j].wARFCN == it->wARFCN)
                {
                    isInList = true;
                    it->count++;
                }
            }

            for (vector<cellItemInfo>::iterator it = UnicomCellItem_.begin(); it != UnicomCellItem_.end(); it++)
            {
                if (MobileCellInfo_[i].stNbCell[j].wARFCN == it->wARFCN)
                {
                    isInList = true;
                    it->count++;
                }
            }
            if (!isInList)
            {
                cellItemInfo tmpInfo;
                tmpInfo.wARFCN =  MobileCellInfo_[i].stNbCell[j].wARFCN;
                bool isMobile = false;
                if ((tmpInfo.wARFCN >= 1 && tmpInfo.wARFCN <= 94)
                    || (tmpInfo.wARFCN >= 512 && tmpInfo.wARFCN <= 636))
                {
                    isMobile = true;
                }
                tmpInfo.wBSIC = MobileCellInfo_[i].stNbCell[j].wBSIC;
                tmpInfo.cRSSI = MobileCellInfo_[i].stNbCell[j].cRSSI;
                tmpInfo.bReserved = MobileCellInfo_[i].stNbCell[j].bReserved;
                tmpInfo.cC1 = MobileCellInfo_[i].stNbCell[j].cC1;
                tmpInfo.bC2 = MobileCellInfo_[i].stNbCell[j].bC2;   
                if (isMobile)
                {
                    MobileCellItem_.push_back(tmpInfo);
                    GSMLogInfo("add gsm mobile ne cell arfcn %d ",  tmpInfo.wARFCN);
                }
                else
                {
                    UnicomCellItem_.push_back(tmpInfo);   
                    GSMLogInfo("add gsm unicom ne cell arfcn %d ",  tmpInfo.wARFCN);        
                }
         
            }
        }

    }

    for (uint32_t i = 0; i < UnicomCellInfo_.size(); i++)
    {
        for (int32_t j = 0; j < UnicomCellInfo_[i].bNbCellNum; j++)
        {
            bool isInList = false;
            for (vector<cellItemInfo>::iterator it = UnicomCellItem_.begin(); it != UnicomCellItem_.end(); it++)
            {
                if (UnicomCellInfo_[i].stNbCell[j].wARFCN == it->wARFCN)
                {
                    isInList = true;
                    it->count++;
                }
            }

            for (vector<cellItemInfo>::iterator it = MobileCellItem_.begin(); it != MobileCellItem_.end(); it++)
            {
                if (UnicomCellInfo_[i].stNbCell[j].wARFCN == it->wARFCN)
                {
                    isInList = true;
                    it->count++;
                }
            }


            if (!isInList)
            {
                cellItemInfo tmpInfo;
                tmpInfo.wARFCN =  UnicomCellInfo_[i].stNbCell[j].wARFCN;
                bool isMobile = false;
                if ((tmpInfo.wARFCN >= 1 && tmpInfo.wARFCN <= 94)
                    || (tmpInfo.wARFCN >= 512 && tmpInfo.wARFCN <= 636))
                {
                    isMobile = true;
                }
                tmpInfo.wBSIC = UnicomCellInfo_[i].stNbCell[j].wBSIC;
                tmpInfo.cRSSI = UnicomCellInfo_[i].stNbCell[j].cRSSI;
                tmpInfo.bReserved = UnicomCellInfo_[i].stNbCell[j].bReserved;
                tmpInfo.cC1 = UnicomCellInfo_[i].stNbCell[j].cC1;
                tmpInfo.bC2 = UnicomCellInfo_[i].stNbCell[j].bC2;   
                if (isMobile)
                {
                    MobileCellItem_.push_back(tmpInfo);
                    GSMLogInfo("add gsm mobile ne cell arfcn %d ",  tmpInfo.wARFCN);
                }
                else
                {
                    UnicomCellItem_.push_back(tmpInfo);   
                    GSMLogInfo("add gsm unicom ne cell arfcn %d ",  tmpInfo.wARFCN);        
                }
            }
        }

    }

    sort(MobileCellItem_.begin(), MobileCellItem_.end(), greater<cellItemInfo>());
    sort(UnicomCellItem_.begin(), UnicomCellItem_.end(), greater<cellItemInfo>());
        
    if (MobileCellItem_.size() > 2 && MobileCellInfo_.size() > 2)
    {
        if (MobileCellItem_[0].wARFCN == MobileCellInfo_[0].wARFCN
                || MobileCellItem_[0].wARFCN == MobileCellInfo_[1].wARFCN)
        {
            MobileCellItem_.erase(MobileCellItem_.begin());
            if (MobileCellItem_[0].wARFCN == MobileCellInfo_[0].wARFCN
                    || MobileCellItem_[0].wARFCN == MobileCellInfo_[1].wARFCN)
            {
                MobileCellItem_.erase(MobileCellItem_.begin());
            }
        }
    }

    if ( UnicomCellItem_.size() > 2 && UnicomCellInfo_.size() > 2)
    {
        if (UnicomCellItem_[0].wARFCN == UnicomCellInfo_[0].wARFCN
                || UnicomCellItem_[0].wARFCN == UnicomCellInfo_[1].wARFCN)
        {
            UnicomCellItem_.erase(UnicomCellItem_.begin());
            if (UnicomCellItem_[0].wARFCN == UnicomCellInfo_[0].wARFCN
                    || UnicomCellItem_[0].wARFCN == UnicomCellInfo_[1].wARFCN)
            {
                UnicomCellItem_.erase(UnicomCellItem_.begin());
            }
        }
    }

    //start

}


void gsmSnfManager::packSnifferResult(stringstream &result, bool isMobileBand900, bool isUnicomBand900)
{
    std::string qm = "\"";
    uint32_t i = 0;
	result << "[";
    
    for ( std::vector<cellItemInfo>::iterator it = MobileCellItem_.begin();  it != MobileCellItem_.end(); it++ )
    {
        i++;
        if (isMobileBand900)
        {
            if (it->wARFCN >= 512)
            {
                continue;
            }
        }
        else
        {
            if (it->wARFCN <= 94)
            {
                continue;
            }
        }
        result << "{";
		result << qm << "cellNumber" << qm << ":" << 8 << ",";
		result << qm << "lac" << qm << ":" << 0 << ",";
		result << qm << "arfcn" << qm << ":" << it->wARFCN << ",";
		result << qm << "bsic" << qm << ":" << it->wBSIC << ",";
		result << qm << "rssi" << qm << ":" << (S16)it->cRSSI << ",";
		result << qm << "c1" << qm << ":" << (S16)it->cC1 << ",";
		result << qm << "c2" << qm << ":" << (U16)it->bC2;

		result << "}";
        
		if ( i == (MobileCellItem_.size() - 1))  continue;
		if (i > 9)
        {
            break;
        }

		result << ",";
    }

    if (i > 0)
    {
        result << ",";
    }
    i = 0;
    for ( std::vector<cellItemInfo>::iterator it = UnicomCellItem_.begin();  it != UnicomCellItem_.end(); it++ )
    {
        i++;
        if (isUnicomBand900)
        {
            if (it->wARFCN >= 637)
            {
                continue;
            }
        }
        else
        {

            if (it->wARFCN <= 124)
            {
                continue;
            }
        }
        result << "{";
		result << qm << "cellNumber" << qm << ":" << 9 << ",";
		result << qm << "lac" << qm << ":" << 0 << ",";
		result << qm << "arfcn" << qm << ":" << it->wARFCN << ",";
		result << qm << "bsic" << qm << ":" << it->wBSIC << ",";
		result << qm << "rssi" << qm << ":" << (S16)it->cRSSI << ",";
		result << qm << "c1" << qm << ":" << (S16)it->cC1 << ",";
		result << qm << "c2" << qm << ":" << (U16)it->bC2;

		result << "}";
		
		if(i == (UnicomCellItem_.size() - 1))  continue;
        if (i > 9)
        {
            break;
        }


		result << ",";
    }

    result << "]";
    result << endl;

}

void gsmSnfManager::packSnfHandleResult(stringstream &result, bool isMobileBand900, bool isUnicomBand900)
{

    uint32_t i = 0;
    if (isMobileBand900)
    {
        result << "config band is 900" <<endl;
    }
    else
    {
        result << "config band is 1800" <<endl;
    }
    for ( std::vector<cellItemInfo>::iterator it = MobileCellItem_.begin();  it != MobileCellItem_.end(); it++ )
    {
        i++;
        if (isMobileBand900)
        {
            if (it->wARFCN >= 512)
            {
                continue;
            }
        }
        else
        {
            if (it->wARFCN <= 94)
            {
                continue;
            }
        }
    
		result << setw(10) << "cellNumber"  << ":" << 8 ;
		result << setw(10)  << "lac"  << ":" << 0 ;
		result << setw(10) << "arfcn" << ":" << it->wARFCN ;
		result << setw(10) << "bsic" << ":" << it->wBSIC ;
		result << setw(10) << "rssi" << ":" << (S16)it->cRSSI ;
		result << setw(10) << "c1" << ":" << (S16)it->cC1 ;
		result << setw(10) << "c2" << ":" << (U16)it->bC2;
        result << setw(10) << "count" << ":" << it->count;

		result << endl;
        
		if ( i == (MobileCellItem_.size() - 1))  continue;
		if (i > 9)
        {
            break;
        }

	
    }

    i = 0;
    for ( std::vector<cellItemInfo>::iterator it = UnicomCellItem_.begin();  it != UnicomCellItem_.end(); it++ )
    {
        i++;
        if (isUnicomBand900)
        {
            if (it->wARFCN >= 637)
            {
                continue;
            }
        }
        else
        {

            if (it->wARFCN <= 124)
            {
                continue;
            }
        }
		result << setw(10) << "cellNumber"  << ":" << 9;
		result << setw(10)  << "lac"  << ":" << 0 ;
		result << setw(10) << "arfcn" << ":" << it->wARFCN ;
		result << setw(10) << "bsic" << ":" << it->wBSIC;
		result << setw(10) << "rssi" << ":" << (S16)it->cRSSI ;
		result << setw(10) << "c1" << ":" << (S16)it->cC1;
		result << setw(10) << "c2" << ":" << (U16)it->bC2;
        result << setw(10) << "count" << ":" << it->count;

		result << endl;
		
		if(i == (UnicomCellItem_.size() - 1))  continue;
        if (i > 9)
        {
            break;
        }

    }

}
